﻿/**	palette.h
 *	----	Create Time Stamp	--2007-02-10 22:54:15--
 *------------------------------------------------------------------------------
 *	Mean	:画板（相当于windows 的一个窗口）
 *	Author	:Nick Shallery	(nicknide@gmail.com)
 *	Version	:1.0.21.34	(2009-09-19 00:20:06)
 *------------------------------------------------------------------------------
**/	/*YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.*/

#if			!defined(__LOLIX__PRETTY__PALETTE__K_IN_G__)
#define		__LOLIX__PRETTY__PALETTE__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX__LOLI__THREAD__NICK__K_IN_G__)
	#include	"../loli/thread.h"
#endif	//	!defined(__LOLIX__LOLI__THREAD__NICK__K_IN_G__)
#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
#if			!defined(__LOLIX__SOLA__RECT__K_IN_G__)
	#include	"../sola/rect.hpp"
#endif	//	!defined(__LOLIX__SOLA__RECT__K_IN_G__)
#if			!defined(__LOLIX__TOY__REBIND_TYPE__K_IN_G__)
	#include	"../toy/rebind_type.hpp"
#endif	//	!defined(__LOLIX__TOY__REBIND_TYPE__K_IN_G__)

namespace lolix{
	namespace pretty{
		class	palette;
		class	canvas;
		enum	ENUM_RENDER_DEVICE_TYPE;
	}
	namespace loli{
		class	thread;
	}
}


////////////////////////////////////////////////////////////////////////////////////////
//<<	画板类, 等价于一个 WINDOW
//!!	任何一个这样的实例必须传递一个可以读取的消息地址给消息回调(当需要传递消息的时候)
//	query : lolix::pretty::canvas_package
class LOLIX_NO_VTABLE lolix::pretty::palette
	: public lolix::itf
{
public:
	struct					_tagMsg;
	class	msg_call_back;
	typedef	loli::thread::query	_tagRenderCaller;

	typedef	_tagMsg				msg;
	typedef	_tagRenderCaller	render_caller;

	//	sig : 当窗口销毁的时候激活
	LOLIX_DEFINE_FACTORY((0x512c4ad0, 0x5b784863, 0xb13f328a, 0xc02dbde3), (palette** out_ptr, loli::thread*, render_caller*, msg_call_back*, size_type device_type, const wchar_t* title, loli::signal* sig /* = 0 */));
	LOLIX_DECLARE_ITF(lolix::pretty::palette, lolix::itf, (0xce5107a5, 0xf89a4763, 0xb91fe72d, 0x70b5f529));

	//	设置当前画板是否可见((当输入指针为0的时候不可见), 或者仅仅改变绘制区域
	enum SHOW_ORDER
	{
		SHOW_ORDER_POS_CENTER	=	0x00000000	,

		SHOW_ORDER_POS_LEFT		=	0x00000010	,
		SHOW_ORDER_POS_RIGHT	=	0x00000020	,
		SHOW_ORDER_POS_TOP		=	0x00000040	,
		SHOW_ORDER_POS_BOTTOM	=	0x00000080	,

		SHOW_ORDER_POS_FULLSCREEN=	0x000000f0	,

		SHOW_ORDER_Z_TOP		=	0x00000000	,
		SHOW_ORDER_Z_BOTTOM		=	0x00000001	,
		SHOW_ORDER_Z_TOPMOST	=	0x00000002	,

		SHOW_ORDER_AT_CENTER	=	0x00000100	,
	};

	enum RET_TYPE
	{
		RET_TYPE_BREAK	,	//	因为某一个消息回调返回中断循环导致跳出	, 通过第二个参数返回跳出的消息回调
		RET_TYPE_EMPTY	,	//	因为当前线程所拥有窗口为空导致循环跳出	, 另外两个出参返回为空和没有错误
		RET_TYPE_ERROR	,	//	因为某个错误而导致循环跳出				, 通过返回值报告错误
	};

	//--------------------------------------------------------------------------
	//	>> 2007-04-20 00:04:53 >>------------------->> 2007-04-20 00:04:53 >>
		//FUNC>>$	:创建一个画板（就是窗口啦）
			//FUNC>>@0	:[in]	当前绘制线程回调
			//FUNC>>@1	:[in]	消息回调类
			//FUNC>>@2	:[in]	渲染设备类型
			//FUNC>>@3	:[in]	标题
				//FUNC>>#	:LOLIX_RETNV_OK	没有问题
	//--------------------------------------------------------------------------
	//virtual	LOLIX_RETNV	LOLIX_CALL create( loli::thread*, render_thread*, msg_call_back*, size_type device_type, const wchar_t* title)				= 0;

	//	销毁窗口
	LOLIX_INTERFACE(destroy	, LOLIX_RETNV	, (void));
	LOLIX_INTERFACE(show	, LOLIX_RETNV	, (const sola::rect<__int32>*, size_type order));
	//	得到当前画板大小
	LOLIX_INTERFACE(size	, LOLIX_RETNV	, (sola::rect<__int32>* const)const);

	//--------------------------------------------------------------------------
	//	>> 2007-05-15 21:24:42 >>------------------->> 2007-05-15 21:24:42 >>
		//FUNC>>$	:给系统执行一个周期以运行必需的指令(create 里面的 render_thread 里面使用)
			//FUNC>>#	:LOLIX_RETNV_OK	:	表示没有问题
			//			LOLIX_INFO_LOST_SYNC	:	表示当前线程收到退出指令
	//--------------------------------------------------------------------------
	LOLIX_INTERFACE(idle	, LOLIX_RETNV, (void));
	//LOLIX_INTERFACE(wait	, LOLIX_RETNV, (toy::time_span const*)const);
};


class LOLIX_NO_VTABLE lolix::pretty::palette::msg_call_back
	: public lolix::itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::palette::msg_call_back, lolix::itf, (0xa681cb31, 0xc8c247fe, 0x8c37e43a, 0x2e8a152c));
	typedef	_tagMsg	msg;

	enum LOOP_TYPE
	{
		LOOP_TYPE_CONTINUE	,	//	顺利处理, 接下来继续后续消息处理
		LOOP_TYPE_IGNORE	,	//	这种消息不会被处理， 因此尽可能不要发送过来, 也会继续后续请求
		LOOP_TYPE_ABORT		,	//	这次操作中止, 但是以后继续
		//LOOP_TYPE_BREAK		,	//	跳出处理过程
	};
	//!!	这个函数不能抛出异常, 允许在处理的时候动态加入和删除消息回调
	//!!	但是动态加入和删除的消息回调在本回合不一定能够得到消息
	//??	const _tagMsg* const 后面那个 const 表示肯定不会传递一个空的消息结构体过来
	//??	继承的时候可以不用加也能够正常
	LOLIX_INTERFACE(msg_enter	, LOOP_TYPE , (const _tagMsg* const));
};


struct lolix::pretty::palette::_tagMsg
{
	enum MSG_TYPE;
	MSG_TYPE		mtype;
	size_type		uparam;
	ptrdiff_type	lparam;
	void*			pparam;
};


enum lolix::pretty::palette::_tagMsg::MSG_TYPE
{
	MSG_TYPE_CREATE		,	//	no param
	MSG_TYPE_DESTROY	,	//	no param

	//	uparam : bool : is maxmized
	//	pparam	sola::rect<__int32> const* ptr = 0 is hide model
	MSG_TYPE_SIZE		,
	//	uparam	:	low 2 byte	= x
	//				high 2 byte = y
	MSG_TYPE_MOUSEMOVE	,
	//	uparam	:	low 2 byte = x
	//				high 2 byte = y
	//	lparam	:	which key
	MSG_TYPE_MOUSE_DOWN	,
	MSG_TYPE_MOUSE_UP	,

	//	uparam	:	key
	MSG_TYPE_KEY_DOWN	,
	MSG_TYPE_KEY_UP		,

	//	uparam	:	0:	actiev, 1: unactive minimized, 2: unactive normal
	MSG_TYPE_ACTIVE_STATE,
};


SYS_REGIST_TYPE(lolix::pretty::palette);
SYS_REGIST_TYPE(lolix::pretty::palette::_tagMsg);
SYS_REGIST_TYPE(lolix::pretty::palette::_tagMsg::MSG_TYPE);
SYS_REGIST_TYPE(lolix::pretty::palette::msg_call_back);
SYS_REGIST_TYPE(lolix::pretty::palette::factory_type);


//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LOLIX__PRETTY__PALETTE__K_IN_G__)
